package parser;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

import math.Point3f;
import math.TexCoord2f;
import math.Triangle;
import math.Vector3f;

public class ObjectReader {

	private String path;
	private ArrayList<Point3f> points;
	private ArrayList<TexCoord2f> textureCoordinates;
	private ArrayList<Vector3f> normals;
	private ArrayList<Triangle> triangles;
	private Scanner scan;

	public ObjectReader(String fileName) {
		this.path = "XML/" + fileName + ".obj";
	}

	public void analyseObject() throws FileNotFoundException {
		initializeDatastructures();
		String token;
		while (scan.hasNext()) {
			token = scan.next();
			if (token.equals("v"))
				readPoint();
			else if (token.equals("vt"))
				readTextureCoordinate();
			else if (token.equals("vn"))
				readNormal();
			else if (token.equals("f"))
				readTriangle();
		}
	}

	private void readTriangle() {
		String temp;
		String[] points = new String[3];
		String[] textureCoordinates = new String[3];
		String[] normals = new String[3];
		for (int i = 0; i < 3; i++) {
			temp = scan.next();
			String[] splits = temp.split("/");
			points[i] = splits[0];
			if (splits.length == 3) {
				textureCoordinates[i] = splits[1];
				normals[i] = splits[2];
			}else{
				textureCoordinates[i] = "";
				normals[i] = "";
			}
		}
		if (!textureCoordinates[0].equals("") && !normals[0].equals("")) {
			triangles.add(new Triangle(
					this.points.get(Integer.parseInt(points[0]) - 1),
					this.points.get(Integer.parseInt(points[1]) - 1),
					this.points.get(Integer.parseInt(points[2]) - 1),
					this.textureCoordinates.get(Integer.parseInt(textureCoordinates[0]) - 1),
					this.textureCoordinates.get(Integer
							.parseInt(textureCoordinates[1]) - 1),
					this.textureCoordinates.get(Integer
							.parseInt(textureCoordinates[2]) - 1), this.normals
							.get(Integer.parseInt(normals[0]) - 1),
					this.normals.get(Integer.parseInt(normals[1]) - 1),
					this.normals.get(Integer.parseInt(normals[2]) - 1)));
		} else if (textureCoordinates[0].equals("") && !normals[0].equals("")) {
			triangles.add(new Triangle(this.points.get(Integer
					.parseInt(points[0]) - 1), this.points.get(Integer
					.parseInt(points[1]) - 1), this.points.get(Integer
					.parseInt(points[2]) - 1), this.normals.get(Integer
					.parseInt(normals[0]) - 1), this.normals.get(Integer
					.parseInt(normals[1]) - 1), this.normals.get(Integer
					.parseInt(normals[2]) - 1)));
		} else if(textureCoordinates[0].equals("") && normals[0].equals("")){
			triangles.add(new Triangle(this.points.get(Integer
					.parseInt(points[0]) - 1), this.points.get(Integer
					.parseInt(points[1]) - 1), this.points.get(Integer
					.parseInt(points[2]) - 1)));
		}
	}

	private void readNormal() {
		float x, y, z;
		x = Float.parseFloat(scan.next());
		y = Float.parseFloat(scan.next());
		z = Float.parseFloat(scan.next());
		normals.add(new Vector3f(x, y, z));
	}

	private void readTextureCoordinate() {
		float u, v;
		u = Float.parseFloat(scan.next());
		v = Float.parseFloat(scan.next());
		textureCoordinates.add(new TexCoord2f(u, v));
	}

	private void readPoint() {
		float x, y, z;
		x = Float.parseFloat(scan.next());
		y = Float.parseFloat(scan.next());
		z = Float.parseFloat(scan.next());
		points.add(new Point3f(x, y, z));
	}

	private void initializeDatastructures() throws FileNotFoundException {
		points = new ArrayList<Point3f>();
		textureCoordinates = new ArrayList<TexCoord2f>();
		normals = new ArrayList<Vector3f>();
		triangles = new ArrayList<Triangle>();
		scan = new Scanner(new File(path));
	}

	public ArrayList<Triangle> getTriangles() {
		return this.triangles;
	}
}
